using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Xml.Serialization;
using System.Xml;

namespace SP
{
    public class ShaderState
    {
        public List<string> Parameters = new List<string>();
        public List<string> Preprocessors = new List<string>();
        public List<string> Fusions = new List<string>();
        
        public ShaderState()
        {
        }

        public static ShaderState FromShader(Shader shader)
        {
            ShaderState state = new ShaderState();

            // add properties of fusions
            foreach (IFusion f in shader.Fusions)
            {
                string fName = f.Name;

                // fusion
                state.Fusions.Add(String.Format("{0};{1};{2}", f.Name, "Enabled", f.Enabled));

                // preprocessors
                foreach (Preprocessor pp in f.Preprocessors)
                {
                    state.Preprocessors.Add(String.Format("{0};{1};{2}", f.Name, pp.Name, pp.Value));
                }

                // parameters
                foreach (IParameter pa in f.Parameters)
                {
                    state.Parameters.Add(String.Format("{0};{1};{2}", f.Name, pa.Name, pa.Value));
                }
            }

            return state;
        }

        public static void ToShader(ShaderState state, Shader outShader)
        {
            outShader.Fusions.Clear();
            IReactor reactor = ReactorDB.Singleton.GetReactorByName(outShader.Reactor);

            if (null == reactor)
                return;

            reactor.InitShader(outShader);

            // fusion properties
            foreach (string s in state.Fusions)
            {
                string[] tokens = s.Split(new char[] { ';' });
                if (tokens.Length < 2) continue;

                IFusion f = GetFusion(outShader, tokens[0]);
                if (null == f) continue;

                switch (tokens[1])
                {
                    case "Enabled":
                        f.Enabled = bool.Parse(tokens[2]);
                        break;
                }
            }

            // fusion preprocessors
            foreach (string s in state.Preprocessors)
            {
                string[] tokens = s.Split(new char[] { ';' });
                if (tokens.Length < 2) continue;

                IFusion f = GetFusion(outShader, tokens[0]);
                if (null == f) continue;

                Preprocessor pp = f.GetPreprocessor(tokens[1]);
                if (null == pp) continue;

                pp.Value = int.Parse(tokens[2]);
            }

            // fusion parameters
            foreach (string s in state.Parameters)
            {
                string[] tokens = s.Split(new char[] { ';' });
                if (tokens.Length < 2) continue;

                IFusion f = GetFusion(outShader, tokens[0]);
                if (null == f) continue;

                IParameter pa = f.GetParameter(tokens[1]);
                if (null == pa) continue;

                pa.Value = tokens[2];
            }
        }

        private static IFusion GetFusion(Shader shader, string fName)
        {
            foreach (IFusion f in shader.Fusions)
                if (f.Name.Equals(fName))
                    return f;

            return null;
        }
    }
}
